<!-- @format -->

<template>
  <button
    :class="buttonClass"
    :disabled="disabled || loading"
    :type="nativeType"
    @click="handleClick"
  >
    <!-- 加载图标 -->
    <span v-if="loading" class="comp-button__loading">
      <svg class="comp-button__loading-icon" viewBox="0 0 1024 1024">
        <path
          d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C637 83.6 579.4 72 520 72s-117 11.6-171.3 34.6a440.45 440.45 0 00-139.9 94.3 437.71 437.71 0 00-94.3 139.9C91.6 395 80 452.6 80 512s11.6 117 34.6 171.3a440.45 440.45 0 0094.3 139.9 437.71 437.71 0 00139.9 94.3C395 940.4 452.6 952 512 952s117-11.6 171.3-34.6a440.45 440.45 0 00139.9-94.3 437.71 437.71 0 0094.3-139.9C940.4 629 952 571.4 952 512c0-19.9 16.1-36 36-36s36 16.1 36 36c0 141.4-55.1 274.4-155.1 374.4S653.4 1042 512 1042 237.6 986.9 137.6 886.9 82 653.4 82 512s55.1-274.4 155.1-374.4S370.6-18 512-18s274.4 55.1 374.4 155.1S1042 370.6 1042 512c0 19.9-16.1 36-36 36z"
        ></path>
      </svg>
    </span>

    <!-- 按钮内容 -->
    <span class="comp-button__content">
      <slot></slot>
    </span>
  </button>
</template>

<script setup lang="ts">
  import { computed } from 'vue'

  // 定义 props
  interface ButtonProps {
    type?:
      | 'primary'
      | 'success'
      | 'warning'
      | 'danger'
      | 'info'
      | 'text'
      | 'default'
    size?: 'large' | 'default' | 'small'
    disabled?: boolean
    loading?: boolean
    plain?: boolean
    round?: boolean
    circle?: boolean
    nativeType?: 'button' | 'submit' | 'reset'
  }

  const props = withDefaults(defineProps<ButtonProps>(), {
    type: 'default',
    size: 'default',
    disabled: false,
    loading: false,
    plain: false,
    round: false,
    circle: false,
    nativeType: 'button',
  })

  // 定义 emits
  const emit = defineEmits<{
    click: [event: MouseEvent]
  }>()

  // 计算按钮的 class
  const buttonClass = computed(() => {
    return [
      'comp-button',
      `comp-button--${props.type}`,
      `comp-button--${props.size}`,
      {
        'is-disabled': props.disabled,
        'is-loading': props.loading,
        'is-plain': props.plain,
        'is-round': props.round,
        'is-circle': props.circle,
      },
    ]
  })

  // 处理点击事件
  const handleClick = (event: MouseEvent) => {
    if (props.disabled || props.loading) {
      event.preventDefault()
      return
    }
    emit('click', event)
  }
</script>

<style scoped>
  .comp-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    height: 32px;
    white-space: nowrap;
    cursor: pointer;
    background: #fff;
    border: 1px solid #dcdfe6;
    color: #606266;
    text-align: center;
    box-sizing: border-box;
    outline: none;
    margin: 0;
    font-weight: 500;
    padding: 8px 15px;
    font-size: 14px;
    border-radius: 4px;
    transition: 0.1s;
    user-select: none;
    vertical-align: middle;
  }

  .comp-button:hover,
  .comp-button:focus {
    color: #409eff;
    border-color: #c6e2ff;
    background-color: #ecf5ff;
  }

  .comp-button:active {
    color: #3a8ee6;
    border-color: #3a8ee6;
    outline: none;
  }

  /* 禁用状态 */
  .comp-button.is-disabled,
  .comp-button.is-disabled:hover,
  .comp-button.is-disabled:focus {
    color: #c0c4cc;
    cursor: not-allowed;
    background-image: none;
    background-color: #fff;
    border-color: #ebeef5;
  }

  /* 加载状态 */
  .comp-button.is-loading {
    position: relative;
    pointer-events: none;
  }

  .comp-button__loading {
    display: inline-flex;
    align-items: center;
    margin-right: 6px;
  }

  .comp-button__loading-icon {
    width: 14px;
    height: 14px;
    animation: rotating 2s linear infinite;
    fill: currentColor;
  }

  @keyframes rotating {
    0% {
      transform: rotate(0deg);
    }
    100% {
      transform: rotate(360deg);
    }
  }

  /* 按钮类型样式 */
  .comp-button--primary {
    color: #fff;
    background-color: #409eff;
    border-color: #409eff;
  }

  .comp-button--primary:hover,
  .comp-button--primary:focus {
    background: #66b1ff;
    border-color: #66b1ff;
    color: #fff;
  }

  .comp-button--primary:active {
    background: #3a8ee6;
    border-color: #3a8ee6;
    color: #fff;
  }

  .comp-button--primary.is-disabled,
  .comp-button--primary.is-disabled:hover,
  .comp-button--primary.is-disabled:focus {
    color: #fff;
    background-color: #a0cfff;
    border-color: #a0cfff;
  }

  .comp-button--success {
    color: #fff;
    background-color: #67c23a;
    border-color: #67c23a;
  }

  .comp-button--success:hover,
  .comp-button--success:focus {
    background: #85ce61;
    border-color: #85ce61;
    color: #fff;
  }

  .comp-button--success:active {
    background: #5daf34;
    border-color: #5daf34;
    color: #fff;
  }

  .comp-button--success.is-disabled,
  .comp-button--success.is-disabled:hover,
  .comp-button--success.is-disabled:focus {
    color: #fff;
    background-color: #b3e19d;
    border-color: #b3e19d;
  }

  .comp-button--warning {
    color: #fff;
    background-color: #e6a23c;
    border-color: #e6a23c;
  }

  .comp-button--warning:hover,
  .comp-button--warning:focus {
    background: #ebb563;
    border-color: #ebb563;
    color: #fff;
  }

  .comp-button--warning:active {
    background: #cf9236;
    border-color: #cf9236;
    color: #fff;
  }

  .comp-button--warning.is-disabled,
  .comp-button--warning.is-disabled:hover,
  .comp-button--warning.is-disabled:focus {
    color: #fff;
    background-color: #f3d19e;
    border-color: #f3d19e;
  }

  .comp-button--danger {
    color: #fff;
    background-color: #f56c6c;
    border-color: #f56c6c;
  }

  .comp-button--danger:hover,
  .comp-button--danger:focus {
    background: #f78989;
    border-color: #f78989;
    color: #fff;
  }

  .comp-button--danger:active {
    background: #dd6161;
    border-color: #dd6161;
    color: #fff;
  }

  .comp-button--danger.is-disabled,
  .comp-button--danger.is-disabled:hover,
  .comp-button--danger.is-disabled:focus {
    color: #fff;
    background-color: #fab6b6;
    border-color: #fab6b6;
  }

  .comp-button--info {
    color: #fff;
    background-color: #909399;
    border-color: #909399;
  }

  .comp-button--info:hover,
  .comp-button--info:focus {
    background: #a6a9ad;
    border-color: #a6a9ad;
    color: #fff;
  }

  .comp-button--info:active {
    background: #82848a;
    border-color: #82848a;
    color: #fff;
  }

  .comp-button--info.is-disabled,
  .comp-button--info.is-disabled:hover,
  .comp-button--info.is-disabled:focus {
    color: #fff;
    background-color: #c8c9cc;
    border-color: #c8c9cc;
  }

  .comp-button--text {
    border-color: transparent;
    color: #409eff;
    background: transparent;
    padding-left: 0;
    padding-right: 0;
  }

  .comp-button--text:hover,
  .comp-button--text:focus {
    color: #66b1ff;
    border-color: transparent;
    background-color: transparent;
  }

  .comp-button--text:active {
    color: #3a8ee6;
    border-color: transparent;
    background-color: transparent;
  }

  .comp-button--text.is-disabled,
  .comp-button--text.is-disabled:hover,
  .comp-button--text.is-disabled:focus {
    border-color: transparent;
  }

  /* 尺寸样式 */
  .comp-button--large {
    height: 40px;
    padding: 12px 19px;
    font-size: 14px;
    border-radius: 4px;
  }

  .comp-button--small {
    height: 24px;
    padding: 5px 11px;
    font-size: 12px;
    border-radius: 3px;
  }

  /* 朴素按钮 */
  .comp-button.is-plain {
    background: #fff;
    border-color: #dcdfe6;
    color: #606266;
  }

  .comp-button--primary.is-plain {
    color: #409eff;
    background: #ecf5ff;
    border-color: #b3d8ff;
  }

  .comp-button--primary.is-plain:hover,
  .comp-button--primary.is-plain:focus {
    background: #409eff;
    border-color: #409eff;
    color: #fff;
  }

  .comp-button--success.is-plain {
    color: #67c23a;
    background: #f0f9ff;
    border-color: #c2e7b0;
  }

  .comp-button--success.is-plain:hover,
  .comp-button--success.is-plain:focus {
    background: #67c23a;
    border-color: #67c23a;
    color: #fff;
  }

  .comp-button--warning.is-plain {
    color: #e6a23c;
    background: #fdf6ec;
    border-color: #f5dab1;
  }

  .comp-button--warning.is-plain:hover,
  .comp-button--warning.is-plain:focus {
    background: #e6a23c;
    border-color: #e6a23c;
    color: #fff;
  }

  .comp-button--danger.is-plain {
    color: #f56c6c;
    background: #fef0f0;
    border-color: #fbc4c4;
  }

  .comp-button--danger.is-plain:hover,
  .comp-button--danger.is-plain:focus {
    background: #f56c6c;
    border-color: #f56c6c;
    color: #fff;
  }

  .comp-button--info.is-plain {
    color: #909399;
    background: #f4f4f5;
    border-color: #d3d4d6;
  }

  .comp-button--info.is-plain:hover,
  .comp-button--info.is-plain:focus {
    background: #909399;
    border-color: #909399;
    color: #fff;
  }

  /* 圆角按钮 */
  .comp-button.is-round {
    border-radius: 20px;
    padding: 8px 23px;
  }

  /* 圆形按钮 */
  .comp-button.is-circle {
    border-radius: 50%;
    padding: 8px;
    width: 32px;
    height: 32px;
  }

  .comp-button--large.is-circle {
    width: 40px;
    height: 40px;
    padding: 12px;
  }

  .comp-button--small.is-circle {
    width: 24px;
    height: 24px;
    padding: 5px;
  }

  .comp-button__content {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
</style>
